package com.excel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * @author xiang
 * @create 2021/6/24 11:06
 */
@Slf4j
public class BaseListener<T> extends AnalysisEventListener<T> {
    /**
     * 每隔3000条存储数据库，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 1000;
    /**
     * 数据list
     */
    List<T> dataEntity = new ArrayList();
    /**
     * 错误信息接收变量
     */
    StringBuilder msg;
    int errorNum = 0;
    int total = 0;
    boolean isTest = false;
    /**
     * 保存函数，批量报错
     */
    SaveFunction saveFunction;
    /**
     * 检查函数，逐条检查
     */
    DealFunction dealFunction;
    public BaseListener(StringBuilder msg, DealFunction dealFunction, SaveFunction saveFunction){
        this.msg=msg;
        this.dealFunction = dealFunction;
        this.saveFunction = saveFunction;
    }
    public BaseListener(StringBuilder msg, DealFunction dealFunction){
        this.msg=msg;
        this.isTest=true;
        this.dealFunction = dealFunction;
    }

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param item    one row value. Is is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(T item, AnalysisContext context) {
        total++;
        if (isTest) {
            try {
                checkout(item);
            }catch (ExcelException exception){
                msg.append("\t第").append(total).append("行存在异常:").append(exception.getMessage()).append("\n");
                errorNum++;
            }
        } else {
            checkout(item);

            dataEntity.add(item);
            if (total>=BATCH_COUNT){
                saveBatch();
            }
        }
    }

    /**
     * @Author xiang
     * @Description 对数据项进行校验，不符合要求返回false
     * @Date 11:49 2021/6/24
     * @Param [item]
     **/
    private boolean checkout(Object item){
        this.dealFunction.check(item);
        return true;
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        if (isTest) {
            msg.insert(0, "总共" + total + "条数据，其中异常条数为" + errorNum + ",异常条目：\n");
        } else {
            saveBatch();
            msg.append("数据导入完成，总数据项").append(total).append("条，导入成功").append(total - errorNum).append("条");
            log.info("所有数据解析完成！");
        }
    }
/**
 * @Author xiang
 * @Description 批量保存
 * @Date 12:04 2021/6/24
 * @Param []
 **/
     void saveBatch(){
         saveFunction.save(dataEntity);
         dataEntity.clear();
     }

}
